﻿#include <iostream>
#include <memory>
#include <vector>
#include "MyClass.h"
#include "Node.h"
#include <random>
#include <iomanip>
#include <codecvt>



int main()
{
	/*
	智能指针是 <memory> 头文件中的核心内容。它们是 C++11 引入的特性，用于自动管理动态分配的内存。智能指针的主要类型有：
	 std::unique_ptr：独占所有权的智能指针，同一时间只能有一个 unique_ptr 指向特定内存。
	 std::shared_ptr：共享所有权的智能指针，多个 shared_ptr 可以指向同一内存，内存在最后一个 shared_ptr 被销毁时释放。
	 std::weak_ptr：弱引用智能指针，用于与 shared_ptr 配合使用，避免循环引用导致的内存泄漏。
	 */


	std::unique_ptr<MyClass> myPtr(new MyClass());
	myPtr->doSomething(); // 使用智能指针调用成员函数

	std::shared_ptr<MyClass> myPtr1(new MyClass());
	std::shared_ptr<MyClass> myPtr2 = myPtr1;

	myPtr1->doSomething(); // 使用 myPtr1 调用成员函数
	myPtr2->doSomething(); // 使用 myPtr2 调用成员函数

	// 当 main 函数结束时，myPtr 被销毁，自动释放 MyClass 对象的内存
	// 当 myPtr1 和 myPtr2 都被销毁时，MyClass 对象的内存才会被释放


	std::shared_ptr<Node> node1 = std::make_shared<Node>();
	std::shared_ptr<Node> node2 = std::make_shared<Node>();

	node1->next = node2;
	node2->prev = node1;
	// 循环引用，但使用 weak_ptr 避免了内存泄漏



	//std::allocator 是标准分配器，提供了基本的内存分配和释放功能。
	//std::allocator<int> alloc;
	//int* p = alloc.allocate(1); // 分配内存
	//alloc.construct(p, 42); // 构造对象
	//std::cout << *p << std::endl;
	//alloc.destroy(p); // 销毁对象
	//alloc.deallocate(p, 1); // 释放内存


	//std::align 用于调整指针的对齐方式，以确保所分配内存满足特定对齐要求。
	alignas(16) char buffer[64];
	void* p2 = buffer;
	size_t space = sizeof(buffer);

	void* aligned_ptr = std::align(16, sizeof(int), p2, space);
	if (aligned_ptr)
	{
		std::cout << "Memory aligned\n";
	}
	else {
		std::cout << "Memory alignment failed\n";
	}



	//new 运算符用于在堆上分配内存
	MyClass* myObject = new MyClass; // 分配一个 MyClass 对象
	myObject->value = 10; // 使用点操作符访问成员
	std::cout << "Value: " << myObject->value << std::endl;
	delete myObject; // 释放内存


	int* myArray = new int[10]; // 分配一个包含10个整数的数组
	for (int i = 0; i < 10; ++i) {
		myArray[i] = i * 2; // 初始化数组
	}

	for (int i = 0; i < 10; ++i) {
		std::cout << "Array[" << i << "]: " << myArray[i] << std::endl;
	}

	delete[] myArray; // 释放数组内存


	//当使用 new 运算符分配内存失败时，C++ 会抛出一个 std::bad_alloc 异常
	try {
		int* myArray = new int[10000000]; // 尝试分配一个大数组
		std::cout << "Memory allocation succeeded." << std::endl;
		delete[] myArray; // 释放内存
	}
	catch (const std::bad_alloc& e) {
		std::cout << "Exception caught: " << e.what() << std::endl;
	}




	//<utility> 头文件包含了一些实用的工具类和函数
	 // 方式1：直接初始化
	std::pair<int, std::string> student1(101, "Alice");

	// 方式2：使用 make_pair 函数（推荐）
	auto student2 = std::make_pair(102, "Bob");

	// 方式3：C++17 起支持的推导指引
	std::pair student3(103, "Charlie");

	// 访问 pair 的成员
	std::cout << "学号: " << student1.first << ", 姓名: " << student1.second << std::endl;


	// 在容器中使用特别方便
	std::vector<std::pair<int, std::string>> students;
	students.push_back(std::make_pair(101, "Alice"));
	students.push_back(std::make_pair(102, "Bob"));

	for (const auto& student : students) {
		std::cout << "学号: " << student.first
			<< ", 姓名: " << student.second << std::endl;
	}




	/*
	<random> 不仅支持生成伪随机数，还支持种子控制、各种概率分布等，使得开发者可以灵活地生成符合特定需求的随机数序列。
	<random> 库由以下三个主要组件构成：
	随机数引擎：生成伪随机数的核心，用于控制生成过程的可重复性和随机性。
	随机数分布：控制生成的数值遵循的概率分布类型。
	随机数适配器：允许调整引擎行为，如 discard_block 等适配器。
	*/

	// 使用随机设备创建一个随机种子
	std::random_device rd;
	// 使用随机种子初始化 Mersenne Twister 随机数生成器
	std::mt19937 generator(rd());
	// 生成一个随机数
	std::cout << "Random number: " << generator() << std::endl;


	//使用均匀分布
	// 创建随机数生成器
	std::mt19937 generator2;
	// 创建一个均匀分布的随机数生成器，范围从 1 到 10
	std::uniform_int_distribution<int> distribution(1, 10);
	// 生成并打印 5 个随机数
	for (int i = 0; i < 5; ++i) {
		std::cout << "Random number: " << distribution(generator2) << std::endl;
	}



	//使用正态分布
	 // 创建随机数生成器
	std::mt19937 generator3;
	// 创建一个正态分布的随机数生成器，均值为 0，标准差为 1
	std::normal_distribution<double> distribution2(0.0, 1.0);
	// 设置输出格式，保留两位小数
	std::cout << std::fixed << std::setprecision(2);
	// 生成并打印 5 个随机数
	for (int i = 0; i < 5; ++i) {
		std::cout << "Random number: " << distribution2(generator3) << std::endl;
	}










	// 1. 设置种子和随机数引擎
	std::random_device rd2; // 随机设备产生种子
	std::mt19937 gen(rd2()); // 梅森旋转引擎

	// 2. 均匀分布的整数
	std::uniform_int_distribution<> dist_int(1, 100);
	std::cout << "Uniform integer: " << dist_int(gen) << std::endl;

	// 3. 均匀分布的浮点数
	std::uniform_real_distribution<> dist_real(0.0, 1.0);
	std::cout << "Uniform real: " << dist_real(gen) << std::endl;

	// 4. 正态分布
	std::normal_distribution<> dist_normal(0, 1);
	std::cout << "Normal: " << dist_normal(gen) << std::endl;

	// 5. 离散分布
	std::discrete_distribution<> dist_discrete({ 10, 20, 70 });
	std::cout << "Discrete: " << dist_discrete(gen) << std::endl;


}
